/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：
* CreateTime：2020-07-07 14:56:32
* Version：1.0
* Modify Recorder：
*************************************************/

using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace TinyToolKitEditor
{
    public class DrawWindowSetup : DrawWindowBase
    {
        private bool isEnableDebug;
        private bool isEnableInfo;
        private bool isEnableWarning;
        private bool isEnableError;

        private const string EnableDebugScriptingDefine = "ENABLE_DEBUG";
        private const string EnableInfoScriptingDefine = "ENABLE_INFO";
        private const string EnableWarningScriptingDefine = "ENABLE_WARNING";
        private const string EnableErrorScriptingDefine = "ENABLE_ERROR";
        
        private ReorderableList _projectDirList;
        private SerializedObject _serializedObject;
        private TinyToolEditorSettingAsset _toolSeting;
        
        public override void InitWindow(ScriptableObject setting)
        {
            _toolSeting = (TinyToolEditorSettingAsset)setting;
            _serializedObject = new SerializedObject(setting);
            
            _projectDirList = TinyToolWindowUtil.GetReorderableList(_serializedObject, "ProjectDirList", "项目文件列表","路径");  
        }

        private BuildTargetGroup[] buildTargetGroups = 
        {
            BuildTargetGroup.Standalone,
            BuildTargetGroup.Android,
            BuildTargetGroup.iOS,
            BuildTargetGroup.WSA,
            BuildTargetGroup.WebGL
        };
        
        protected override void DrawInternalMainGUI()
        {
            _serializedObject.Update();

            _toolSeting.appTitle = TinyToolWindowUtil.DrawTextField("项目名：", _toolSeting.appTitle);
            _toolSeting.author = TinyToolWindowUtil.DrawTextField("开发者：", _toolSeting.author);

            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("日志输出：", GUILayout.MaxWidth(150));
            if (EditorGUILayout.DropdownButton(new GUIContent("日志宏定义"), FocusType.Keyboard,
                new GUIStyle("DropDownButton"), GUILayout.MaxWidth(150)))
            {
                GenericMenu menu = new GenericMenu();
                menu.AddItem(new GUIContent(EnableDebugScriptingDefine), isEnableDebug, OnSelectedLogDefine,
                    EnableDebugScriptingDefine);
                menu.AddItem(new GUIContent(EnableInfoScriptingDefine), isEnableInfo, OnSelectedInfoDefine,
                    EnableInfoScriptingDefine);
                menu.AddItem(new GUIContent(EnableWarningScriptingDefine), isEnableWarning, OnSelectedWarningDefine,
                    EnableWarningScriptingDefine);
                menu.AddItem(new GUIContent(EnableErrorScriptingDefine), isEnableError, OnSelectedErrorDefine,
                    EnableErrorScriptingDefine);
                menu.ShowAsContext();
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.Space();
            
            _projectDirList.DoLayoutList();
            
            _serializedObject.ApplyModifiedProperties();
        }

        private void OnSelectedLogDefine(object value)
        {
            isEnableDebug = !isEnableDebug;
            if (isEnableDebug)
                AddScriptingDefineSymbolToAllBuildTarget(value.ToString());
            else
                RemoveScriptingDefineSymbolFromAllBuildTarget(value.ToString());
        }

        private void OnSelectedInfoDefine(object value)
        {
            isEnableInfo = !isEnableInfo;
            if (isEnableInfo)
                AddScriptingDefineSymbolToAllBuildTarget(value.ToString());
            else
                RemoveScriptingDefineSymbolFromAllBuildTarget(value.ToString());
        }

        private void OnSelectedWarningDefine(object value)
        {
            isEnableWarning = !isEnableWarning;
            if (isEnableWarning)
                AddScriptingDefineSymbolToAllBuildTarget(value.ToString());
            else
                RemoveScriptingDefineSymbolFromAllBuildTarget(value.ToString());
        }

        private void OnSelectedErrorDefine(object value)
        {
            isEnableError = !isEnableError;
            if (isEnableError)
                AddScriptingDefineSymbolToAllBuildTarget(value.ToString());
            else
                RemoveScriptingDefineSymbolFromAllBuildTarget(value.ToString());
        }
   
        public void CheckScriptingDefineSymbol(BuildTargetGroup buildTargetGroup)
        {
            string[] scriptingDefineSymbols = GetScriptingDefineSymbols(buildTargetGroup);

            for (int i = 0; i < scriptingDefineSymbols.Length; i++)
            {
                string symbols = scriptingDefineSymbols[i];
                if (symbols == EnableDebugScriptingDefine)
                    isEnableDebug = true;
                else if (symbols == EnableInfoScriptingDefine)
                    isEnableInfo = true;
                else if (symbols == EnableWarningScriptingDefine)
                    isEnableWarning = true;
                else if (symbols == EnableErrorScriptingDefine)
                    isEnableError = true;
            }
        }

        /// <summary>
        /// 为所有平台增加指定的脚本宏定义。 
        /// </summary>
        /// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param> 
        private void AddScriptingDefineSymbolToAllBuildTarget(string scriptingDefineSymbol)
        {
            foreach (BuildTargetGroup buildTargetGroup in buildTargetGroups)
            {
                AddScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
            }
        }

        /// <summary>
        /// 为所有平台移除指定的脚本宏定义。
        /// </summary>
        /// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param> 
        private void RemoveScriptingDefineSymbolFromAllBuildTarget(string scriptingDefineSymbol)
        {
            foreach (BuildTargetGroup buildTargetGroup in buildTargetGroups)
            {
                RemoveScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol);
            }
        }

        /// <summary>
        /// 为指定平台增加指定的脚本宏定义。
        /// </summary>
        /// <param name="buildTargetGroup">要增加脚本宏定义的平台。</param>
        /// <param name="scriptingDefineSymbol">要增加的脚本宏定义。</param>
        private void AddScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
        {
            if (string.IsNullOrEmpty(scriptingDefineSymbol)) return;
            if (HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol)) return;

            List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup));
            scriptingDefineSymbols.Add(scriptingDefineSymbol);

            SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
        }

        /// <summary>
        /// 为指定平台移除指定的脚本宏定义。
        /// </summary>
        /// <param name="buildTargetGroup">要移除脚本宏定义的平台。</param>
        /// <param name="scriptingDefineSymbol">要移除的脚本宏定义。</param>
        private void RemoveScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
        {
            if (string.IsNullOrEmpty(scriptingDefineSymbol)) return;
            if (!HasScriptingDefineSymbol(buildTargetGroup, scriptingDefineSymbol)) return;

            List<string> scriptingDefineSymbols = new List<string>(GetScriptingDefineSymbols(buildTargetGroup));

            if (scriptingDefineSymbols.Contains(scriptingDefineSymbol))
            {
                scriptingDefineSymbols.Remove(scriptingDefineSymbol);
            }

            SetScriptingDefineSymbols(buildTargetGroup, scriptingDefineSymbols.ToArray());
        }

        /// <summary>
        /// 检查指定平台是否存在指定的脚本宏定义。
        /// </summary>
        /// <param name="buildTargetGroup">要检查脚本宏定义的平台。</param>
        /// <param name="scriptingDefineSymbol">要检查的脚本宏定义。</param>
        /// <returns>指定平台是否存在指定的脚本宏定义。</returns>
        private bool HasScriptingDefineSymbol(BuildTargetGroup buildTargetGroup, string scriptingDefineSymbol)
        {
            if (string.IsNullOrEmpty(scriptingDefineSymbol)) return false;

            string[] scriptingDefineSymbols = GetScriptingDefineSymbols(buildTargetGroup);
            foreach (string symbol in scriptingDefineSymbols)
            {
                if (symbol == scriptingDefineSymbol)
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 获取指定平台的脚本宏定义。
        /// </summary>
        /// <param name="buildTargetGroup">要获取脚本宏定义的平台。</param>
        /// <returns>平台的脚本宏定义。</returns>
        private string[] GetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup)
        {
            return PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';');
        }

        /// <summary>
        /// 设置指定平台的脚本宏定义。
        /// </summary>
        /// <param name="buildTargetGroup">要设置脚本宏定义的平台。</param>
        /// <param name="scriptingDefineSymbols">要设置的脚本宏定义。</param>
        private void SetScriptingDefineSymbols(BuildTargetGroup buildTargetGroup, string[] scriptingDefineSymbols)
        {
            PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup,
                string.Join(";", scriptingDefineSymbols));
        }
    }
}